<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow-IPC: ipc::util::sync_io::Timer_event_emitter Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow-IPC<span id="projectnumber">&#160;1.0.2</span>
   </div>
   <div id="projectbrief">Flow-IPC project: Full implementation reference.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceipc.html">ipc</a></li><li class="navelem"><a class="el" href="namespaceipc_1_1util.html">util</a></li><li class="navelem"><a class="el" href="namespaceipc_1_1util_1_1sync__io.html">sync_io</a></li><li class="navelem"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html">Timer_event_emitter</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#pub-types">Public Types</a> &#124;
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-attribs">Public Attributes</a> &#124;
<a href="#pri-attribs">Private Attributes</a> &#124;
<a href="#related">Related Functions</a> &#124;
<a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">ipc::util::sync_io::Timer_event_emitter Class Reference</div></div>
</div><!--header-->
<div class="contents">

<p>An object of this type, used internally to implement <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code>-pattern objects that require timer events, starts a thread dedicated exclusively to running timer waits on the <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code> object's behalf, so that when such a timer fires, it emits a pipe-readable event to be detected by the user's event loop, which it then reports to <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code> object.  
 <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#details">More...</a></p>

<p><code>#include &lt;<a class="el" href="timer__ev__emitter_8hpp_source.html">timer_ev_emitter.hpp</a>&gt;</code></p>
<div class="dynheader">
Inheritance diagram for ipc::util::sync_io::Timer_event_emitter:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter__inherit__graph.svg" width="310" height="119"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<div class="dynheader">
Collaboration diagram for ipc::util::sync_io::Timer_event_emitter:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter__coll__graph.svg" width="764" height="336"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-types" name="pub-types"></a>
Public Types</h2></td></tr>
<tr class="memitem:a1533a54927a64579fda02c61ec94b735"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a> = boost::asio::readable_pipe</td></tr>
<tr class="memdesc:a1533a54927a64579fda02c61ec94b735"><td class="mdescLeft">&#160;</td><td class="mdescRight">Object representing the read end of IPC mechanism, where readable status indicates the associated <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> call has resulted in the timer firing.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">More...</a><br /></td></tr>
<tr class="separator:a1533a54927a64579fda02c61ec94b735"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:a8a4720c9fc5ecb15ce2efee16b4c3cee"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a8a4720c9fc5ecb15ce2efee16b4c3cee">Timer_event_emitter</a> (flow::log::Logger *logger_ptr, <a class="el" href="namespaceipc_1_1util.html#ae6ac47812a90d1287c61e0b7de7bc4f5">String_view</a> nickname_str)</td></tr>
<tr class="memdesc:a8a4720c9fc5ecb15ce2efee16b4c3cee"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs emitter, creating idle thread managing no timers.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a8a4720c9fc5ecb15ce2efee16b4c3cee">More...</a><br /></td></tr>
<tr class="separator:a8a4720c9fc5ecb15ce2efee16b4c3cee"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aab9cd218457e4fa5ce3bb6e1b59542ee"><td class="memItemLeft" align="right" valign="top">flow::util::Timer&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee">create_timer</a> ()</td></tr>
<tr class="memdesc:aab9cd218457e4fa5ce3bb6e1b59542ee"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates idle timer for use with <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> subsequently.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee">More...</a><br /></td></tr>
<tr class="separator:aab9cd218457e4fa5ce3bb6e1b59542ee"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad2124aadd5025490aedf16958db4599c"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c">create_timer_signal_pipe</a> ()</td></tr>
<tr class="memdesc:ad2124aadd5025490aedf16958db4599c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates, and internally stores, an IPC mechanism instance intended for use with a given <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee" title="Creates idle timer for use with timer_async_wait() subsequently.">create_timer()</a>-returned <code>Timer</code>; returns pointer to the read-end of this mechanism.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c">More...</a><br /></td></tr>
<tr class="separator:ad2124aadd5025490aedf16958db4599c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a838497cd832da97bf1d52a7b8a85734c"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c">timer_async_wait</a> (flow::util::Timer *timer, <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a> *read_end)</td></tr>
<tr class="memdesc:a838497cd832da97bf1d52a7b8a85734c"><td class="mdescLeft">&#160;</td><td class="mdescRight">To be used on a timer <code>T</code> returned by <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee" title="Creates idle timer for use with timer_async_wait() subsequently.">create_timer()</a>, this is the replacement for the usual <code>T.async_wait(F)</code> call that loads a completion handler to execute at the expiration time.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c">More...</a><br /></td></tr>
<tr class="separator:a838497cd832da97bf1d52a7b8a85734c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a80a0549f49fafc358763e9325c31256b"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a80a0549f49fafc358763e9325c31256b">consume_timer_firing_signal</a> (<a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a> *read_end)</td></tr>
<tr class="memdesc:a80a0549f49fafc358763e9325c31256b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Must be called after a <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a>-triggered timer fired, before invoking that method for the same <code>Timer</code> again.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a80a0549f49fafc358763e9325c31256b">More...</a><br /></td></tr>
<tr class="separator:a80a0549f49fafc358763e9325c31256b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a96f26e369ac1289b0a684d12f6bf07c3"><td class="memItemLeft" align="right" valign="top">const std::string &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a96f26e369ac1289b0a684d12f6bf07c3">nickname</a> () const</td></tr>
<tr class="memdesc:a96f26e369ac1289b0a684d12f6bf07c3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns nickname as passed to ctor.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a96f26e369ac1289b0a684d12f6bf07c3">More...</a><br /></td></tr>
<tr class="separator:a96f26e369ac1289b0a684d12f6bf07c3"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-attribs" name="pub-attribs"></a>
Public Attributes</h2></td></tr>
<tr class="memitem:a63c1e77a76775134b5a6d4725d58be81"><td class="memItemLeft" align="right" valign="top">const std::string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a63c1e77a76775134b5a6d4725d58be81">m_nickname</a></td></tr>
<tr class="memdesc:a63c1e77a76775134b5a6d4725d58be81"><td class="mdescLeft">&#160;</td><td class="mdescRight">Nickname as passed to ctor.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a63c1e77a76775134b5a6d4725d58be81">More...</a><br /></td></tr>
<tr class="separator:a63c1e77a76775134b5a6d4725d58be81"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-attribs" name="pri-attribs"></a>
Private Attributes</h2></td></tr>
<tr class="memitem:ad17e799f7c36c4c0cbc858637377f456"><td class="memItemLeft" align="right" valign="top">flow::async::Single_thread_task_loop&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad17e799f7c36c4c0cbc858637377f456">m_worker</a></td></tr>
<tr class="memdesc:ad17e799f7c36c4c0cbc858637377f456"><td class="mdescLeft">&#160;</td><td class="mdescRight">The thread where (only) timer-firing events (from <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee" title="Creates idle timer for use with timer_async_wait() subsequently.">create_timer()</a>-created <code>Timer</code>s) execute.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad17e799f7c36c4c0cbc858637377f456">More...</a><br /></td></tr>
<tr class="separator:ad17e799f7c36c4c0cbc858637377f456"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:afafdfa9e2c522cd3e12b4f1915f83b56"><td class="memItemLeft" align="right" valign="top">std::vector&lt; boost::movelib::unique_ptr&lt; <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a> &gt; &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#afafdfa9e2c522cd3e12b4f1915f83b56">m_signal_pipe_readers</a></td></tr>
<tr class="memdesc:afafdfa9e2c522cd3e12b4f1915f83b56"><td class="mdescLeft">&#160;</td><td class="mdescRight">The readers (never null) returned by <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a>.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#afafdfa9e2c522cd3e12b4f1915f83b56">More...</a><br /></td></tr>
<tr class="separator:afafdfa9e2c522cd3e12b4f1915f83b56"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac2e6652bed4a80239d57a7fad2bab47c"><td class="memItemLeft" align="right" valign="top">boost::unordered_map&lt; <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a> *, boost::movelib::unique_ptr&lt; boost::asio::writable_pipe &gt; &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ac2e6652bed4a80239d57a7fad2bab47c">m_signal_pipe_writers</a></td></tr>
<tr class="memdesc:ac2e6652bed4a80239d57a7fad2bab47c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Stores the write-ends of the pipes created in <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a>, indexed by pointer to their respective read-ends.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ac2e6652bed4a80239d57a7fad2bab47c">More...</a><br /></td></tr>
<tr class="separator:ac2e6652bed4a80239d57a7fad2bab47c"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="related" name="related"></a>
Related Functions</h2></td></tr>
<tr><td class="ititle" colspan="2"><p >(Note that these are not member functions.) </p>
</td></tr>
<tr class="memitem:a07ebecd1cab6bf716b3482047e67eeb9"><td class="memItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a07ebecd1cab6bf716b3482047e67eeb9">operator&lt;&lt;</a> (std::ostream &amp;os, const <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html">Timer_event_emitter</a> &amp;val)</td></tr>
<tr class="memdesc:a07ebecd1cab6bf716b3482047e67eeb9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints string representation of the given <code><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html" title="An object of this type, used internally to implement sync_io-pattern objects that require timer event...">Timer_event_emitter</a></code> to the given <code>ostream</code>.  <a href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a07ebecd1cab6bf716b3482047e67eeb9">More...</a><br /></td></tr>
<tr class="separator:a07ebecd1cab6bf716b3482047e67eeb9"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >An object of this type, used internally to implement <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code>-pattern objects that require timer events, starts a thread dedicated exclusively to running timer waits on the <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code> object's behalf, so that when such a timer fires, it emits a pipe-readable event to be detected by the user's event loop, which it then reports to <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code> object. </p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">ipc::util::sync_io</a> for discussion of the <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code> pattern. This is necessary background for the present class which is used in implementing objects within that pattern.</dd></dl>
<h3>Rationale</h3>
<p >In the <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code> pattern, suppose there is <a class="el" href="namespaceipc_1_1transport.html" title="Flow-IPC module providing transmission of structured messages and/or low-level blobs (and more) betwe...">ipc::transport</a> or <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> object X (e.g., <a class="el" href="classipc_1_1transport_1_1sync__io_1_1Native__socket__stream_1_1Impl.html" title="Internal, non-movable pImpl implementation of sync_io::Native_socket_stream class.">ipc::transport::sync_io::Native_socket_stream::Impl</a>). By definiton of the <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code> pattern, X itself endeavours to not async-wait on various events itself, in its own threads it might start, but rather instructs the user to wait on <a class="el" href="structipc_1_1util_1_1Native__handle.html" title="A monolayer-thin wrapper around a native handle, a/k/a descriptor a/k/a FD.">Native_handle</a> being readable or writable and to inform X of such an event (see <a class="el" href="namespaceipc_1_1util_1_1sync__io.html#aa0b9a3cc6bdc7dedbef4f9e06851aa24" title="In sync_io pattern, concrete type storing user-supplied function invoked by pattern-implementing ipc:...">sync_io::Event_wait_func</a> doc header). For example <code>Native_socket_stream::Impl</code>, when awaiting in-traffic, uses <a class="el" href="namespaceipc_1_1util_1_1sync__io.html#aa0b9a3cc6bdc7dedbef4f9e06851aa24" title="In sync_io pattern, concrete type storing user-supplied function invoked by pattern-implementing ipc:...">Event_wait_func</a> to inform itself when the Unix-domain socket has become readable &ndash; the user uses their own <code>[e]poll*()</code> or boost.asio loop or ... to detect the readability and then informs X when this happens.</p>
<p >Some objects, in particular at least various <code>Blob_receiver</code>s and <code>Blob_sender</code>s, also at times wait on timer events; in implementing <a class="el" href="classipc_1_1transport_1_1Blob__receiver.html#a5be288e0479a91e352fdea6d54460b22" title="In PEER state: Irreversibly enables a conceptual idle timer whose potential side effect is,...">transport::Blob_receiver::idle_timer_run()</a> and <a class="el" href="classipc_1_1transport_1_1Blob__sender.html#ac41990a469e61a26ca9cefaf6a291a2e" title="In PEER state: Irreversibly enables periodic auto-pinging of opposing receiver with low-level message...">transport::Blob_sender::auto_ping()</a> respectively. For example if the idle timer fires, then <code>Blob_receiver</code> X needs to know; and if there is an outstanding <code>Blob_receiver::async_receive_blob()</code>, it should not continue being outstanding but rather: (1) The user's event loop &ndash; which might otherwise be in the middle of a blocking <code>epoll_wait()</code> &ndash; must exit any such wait; and (2) X should be informed, in this case so the outstanding receive-op would complete with the idle-timeout error, detectable by the user's event loop before the next <code>epoll_wait()</code>.</p>
<p >But how to even accompish (1)? ((2) is relatively simple in comparison.) Possibilities:</p><ul>
<li>The user can be told of the next-soonest timer's expiration time, so that the <code>epoll_wait()</code> (or <code>poll()</code> or ...) can be set to time out at that time, latest.<ul>
<li>This is viable but presents a tricky API design problem for the <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code> pattern. The next-soonest timer expiration time will change over time, as new timers pop or existing timers are rescheduled. <a class="el" href="namespaceipc_1_1util_1_1sync__io.html#aa0b9a3cc6bdc7dedbef4f9e06851aa24" title="In sync_io pattern, concrete type storing user-supplied function invoked by pattern-implementing ipc:...">Event_wait_func</a> semantics have to be expanded beyond us specifying a mere (FD, read-vs-write flag) pair; it would now specify a timer, and somehow the next-soonest timer across <em>all</em> <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code> objects in use by the user (not just X alone) would need to be computable. Doable but much more complex than a set of decoupled FD+flag pairs, one per <a class="el" href="namespaceipc_1_1util_1_1sync__io.html#aa0b9a3cc6bdc7dedbef4f9e06851aa24" title="In sync_io pattern, concrete type storing user-supplied function invoked by pattern-implementing ipc:...">Event_wait_func</a> invocation.</li>
</ul>
</li>
<li>The OS can be somehow told to tickle a dedicated-to-this-purpose FD (per timer) at a particular time, while <a class="el" href="namespaceipc_1_1util_1_1sync__io.html#aa0b9a3cc6bdc7dedbef4f9e06851aa24" title="In sync_io pattern, concrete type storing user-supplied function invoked by pattern-implementing ipc:...">Event_wait_func</a> is used (same as it is for Unix domain sockets, etc.) to wait for readability of that FD. <code>epoll_wait()</code> (or ...) would wake up like on any other event and inform X, and X would even know which timer it is, by being informed via <code>Event_wait_func</code>'s' <code>on_active_ev_func</code> arg.</li>
</ul>
<p >The latter option is much more attractive in terms of API simplicity from the user's point of view (at least). So we go with that. Having make this decision, how to actually make it work? Possibilities:</p><ul>
<li>The OS has these mechanisms. Linux, at least, has <code>timerfd_create()</code> and buddies, specifically for this. One can schedule a timer, so the kernel keeps track of all that and does it in the background; when ready the FD becomes readable. Done.<ul>
<li>This is a very reasonable approach. However it is not very portable, and the API is hairy enough to require a bunch of (internal to us) wrapping code: specifying the time along the proper clock, rescheduling, canceling....</li>
</ul>
</li>
<li>boost.asio, of course, has <code>flow::util::Timer</code> (a/k/a <code>waitable_timer</code>). <code>Timer::async_wait(F)</code> starts a wait, invoking <code>F</code> in whatever thread(s) are running the <code>Timer</code>'s attached <code>Task_engine</code> (a/k/a <code>io_context</code>); <code>Timer::expires_after()</code> (re)schedules the timer; etc.<ul>
<li>This is a much nicer API, and it is portable and oft-used in the Flow world. The only problem is it is not attached &ndash; in a public way &ndash; to any particular FD. Although boost.asio source shows internally <code>timerfd_create()</code> is used (at least when certain compile-time flags are set), there's no <code>Timer::native_handle()</code> that exposes the timer FD. That said <code>F()</code> can do whatever we want... including pinging some simple (internally-setup) IPC mechanism, like an anonymous pipe, whose read-end is accessed via an FD.</li>
</ul>
</li>
</ul>
<p >Bottom line, we went with the latter approach. It is more elegant. It does, however, require two things which the kernel-timer approach does not:</p><ul>
<li>The IPC mechanism. We use a pipe (per timer). boost.asio even provides portable support for this.</li>
<li>A background thread in which <code>F()</code> would write a byte to this pipe, when the timer fires.<ul>
<li>Threads are easy to set up for us. Isn't this a performance problem though? Answer: No; at least not in our use case. The overhead is in 1, the context switch <em>at the time a timer actually fires</em> and 2, the pipe write and resulting read. These theoretically add latency but <em>only</em> when a timer fires. If we were using timers for something frequent &ndash; like, I don't know, packet pacing &ndash; this would be an issue. We do not: idle timers and auto-ping timers fire at worst seconds apart. There is no real latency impact there over time.</li>
</ul>
</li>
</ul>
<p >So there you have it. We need:</p><ul>
<li>A thread for 1+ timers. E.g., typically, one object X would require one thread for all its timers.</li>
<li>An unnamed pipe per timer. The thread would write to the write end, while object X would read from the read end and give the read-end FD to the user to wait-on via <a class="el" href="namespaceipc_1_1util_1_1sync__io.html#aa0b9a3cc6bdc7dedbef4f9e06851aa24" title="In sync_io pattern, concrete type storing user-supplied function invoked by pattern-implementing ipc:...">Event_wait_func</a>.</li>
<li>Some simple logic such that when a given timer fires, the handler (in the aforementioned thread) merely writes a byte to the associated pipe.</li>
</ul>
<p ><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html" title="An object of this type, used internally to implement sync_io-pattern objects that require timer event...">Timer_event_emitter</a> supplies those things.</p>
<h3>How to use</h3>
<p >Construct <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html" title="An object of this type, used internally to implement sync_io-pattern objects that require timer event...">Timer_event_emitter</a>. This will start an idle thread (and it will remain totally idle with the sole exception of a pipe-write executing when a timer actually fires).</p>
<p >Call <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee" title="Creates idle timer for use with timer_async_wait() subsequently.">create_timer()</a>. This just returns a totally normal <code>flow::util::Timer</code> to be saved in the <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code>-pattern-implementing object. <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee" title="Creates idle timer for use with timer_async_wait() subsequently.">create_timer()</a> merely associates the <code>*this</code> thread with that timer, so that when <code>Timer::async_wait(F)</code> eventually causes <code>F()</code> to execute, it will execute <code>F()</code> in that thread.</p>
<p >Call <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a> (for each timer one plans to use). This creates a pipe; saves both ends inside <code>*this</code>; and returns a pointer to the read-end. The <code><a class="el" href="namespaceipc_1_1util_1_1sync__io.html" title="Contains common code, as well as important explanatory documentation in the following text,...">sync_io</a></code>-pattern object saves this, including so that it can pass the associated <a class="el" href="structipc_1_1util_1_1Native__handle.html" title="A monolayer-thin wrapper around a native handle, a/k/a descriptor a/k/a FD.">Native_handle</a> (FD) to <a class="el" href="namespaceipc_1_1util_1_1sync__io.html#aa0b9a3cc6bdc7dedbef4f9e06851aa24" title="In sync_io pattern, concrete type storing user-supplied function invoked by pattern-implementing ipc:...">Event_wait_func</a>, whenever it begins a timer-wait.</p>
<p >Use the <code>Timer</code> completely as normal, including <code>Timer::expires_after()</code> to schedule and reschedule the firing time... with one exception:</p>
<p >Instead of the usual <code>Timer::async_wait()</code>, call instead <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a>, which takes:</p><ul>
<li>Pointer to the <code>Timer</code>. <code>*this</code> will <code>-&gt;async_wait(F)</code> on that <code>Timer</code>.</li>
<li>Pointer to the associated pipe read-end. <code>*this</code> will use it as a key to determine the associated write-end. <code>F()</code> will simply perform the 1-byte-write to that write-end.</li>
</ul>
<p >(<a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> is, basically, a convenience. We could instead have had <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a> return both the read-end and write-end; and had the <code>*this</code> user memorize both and itself do the <code>Timer::async_wait()</code>, with the handler writing to the write-end. It is nicer to keep that stuff to <code>*this</code>.)</p>
<p >Lastly, when <a class="el" href="namespaceipc_1_1util_1_1sync__io.html#aa0b9a3cc6bdc7dedbef4f9e06851aa24" title="In sync_io pattern, concrete type storing user-supplied function invoked by pattern-implementing ipc:...">Event_wait_func</a> <code>on_active_ev_func()</code> informs the <code>sync_op</code>-pattern-implementing object of a timer-associated FD being readable, it must read the byte off the pipe by calling <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a80a0549f49fafc358763e9325c31256b" title="Must be called after a timer_async_wait()-triggered timer fired, before invoking that method for the ...">consume_timer_firing_signal()</a>. (Again, it's just a convenience. We could have had the user object read the byte themselves. It is nicer to keep the protocol inside <code>*this</code>.)</p>
<h3>Thread safety note</h3>
<p >A given <code>*this</code> itself has boring thread-safety properties: you may not call a non-<code>const</code> method while calling another method. That, however, is unlikely to be interesting.</p>
<p >It is not safe to concurrently call <code>timer_async_wait(&amp;T)</code>, where <code>T</code> is a <code>Timer</code>, with any other method of <code>T</code>. You can think, in this context, of <code>timer_async_wait(&amp;T)</code> as being equivalent to <code>T-&gt;async_wait()</code>. </p>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8hpp_source.html#l00145">145</a> of file <a class="el" href="timer__ev__emitter_8hpp_source.html">timer_ev_emitter.hpp</a>.</p>
</div><h2 class="groupheader">Member Typedef Documentation</h2>
<a id="a1533a54927a64579fda02c61ec94b735" name="a1533a54927a64579fda02c61ec94b735"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1533a54927a64579fda02c61ec94b735">&#9670;&nbsp;</a></span>Timer_fired_read_end</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">ipc::util::sync_io::Timer_event_emitter::Timer_fired_read_end</a> =  boost::asio::readable_pipe</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Object representing the read end of IPC mechanism, where readable status indicates the associated <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> call has resulted in the timer firing. </p>
<p >Formally the <code>*this</code> user shall perform only the following operations on such an object R, after obtaining it from <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a>:</p><ul>
<li>Load your <a class="el" href="classipc_1_1util_1_1sync__io_1_1Asio__waitable__native__handle.html" title="Useful if using the sync_io pattern within a user event loop built on boost.asio (optionally with flo...">Asio_waitable_native_handle</a> <code>E</code> via <code>E.assign(<a class="el" href="structipc_1_1util_1_1Native__handle.html" title="A monolayer-thin wrapper around a native handle, a/k/a descriptor a/k/a FD.">Native_handle</a>(R.native_handle())</code> or equivalent.</li>
<li>Call <code>Event_wait_func</code>, passing in <code>&amp;E</code>, just ahead of <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">Timer_event_emitter::timer_async_wait()</a>.</li>
<li>Call <code>consume_timer_firing_signal(&amp;R)</code> in the handler for the so-registered-via-<code>Event_wait_func</code> event (meaning, if the timer indeed fired). </li>
</ul>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8hpp_source.html#l00162">162</a> of file <a class="el" href="timer__ev__emitter_8hpp_source.html">timer_ev_emitter.hpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="a8a4720c9fc5ecb15ce2efee16b4c3cee" name="a8a4720c9fc5ecb15ce2efee16b4c3cee"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8a4720c9fc5ecb15ce2efee16b4c3cee">&#9670;&nbsp;</a></span>Timer_event_emitter()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">ipc::util::sync_io::Timer_event_emitter::Timer_event_emitter </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1util.html#ae6ac47812a90d1287c61e0b7de7bc4f5">String_view</a>&#160;</td>
          <td class="paramname"><em>nickname_str</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Constructs emitter, creating idle thread managing no timers. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequently logging. </td></tr>
    <tr><td class="paramname">nickname_str</td><td>Human-readable nickname of the new object, as of this writing for use in <code>operator&lt;&lt;(ostream)</code> and logging only. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8cpp_source.html#l00030">30</a> of file <a class="el" href="timer__ev__emitter_8cpp_source.html">timer_ev_emitter.cpp</a>.</p>

<p class="reference">References <a class="el" href="timer__ev__emitter_8hpp_source.html#l00250">m_worker</a>.</p>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a80a0549f49fafc358763e9325c31256b" name="a80a0549f49fafc358763e9325c31256b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a80a0549f49fafc358763e9325c31256b">&#9670;&nbsp;</a></span>consume_timer_firing_signal()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void ipc::util::sync_io::Timer_event_emitter::consume_timer_firing_signal </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a> *&#160;</td>
          <td class="paramname"><em>read_end</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Must be called after a <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a>-triggered timer fired, before invoking that method for the same <code>Timer</code> again. </p>
<p >It reads the small payload that was written at the time of the timer's firing (in the internal-IPC mechanism used for this purpose).</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">read_end</td><td>See <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> and <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a>. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8cpp_source.html#l00123">123</a> of file <a class="el" href="timer__ev__emitter_8cpp_source.html">timer_ev_emitter.cpp</a>.</p>

<p class="reference">References <a class="el" href="ipc__core_2src_2ipc_2util_2detail_2util_8cpp_source.html#l00096">ipc::util::pipe_consume()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter_a80a0549f49fafc358763e9325c31256b_cgraph.svg" width="356" height="71"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="aab9cd218457e4fa5ce3bb6e1b59542ee" name="aab9cd218457e4fa5ce3bb6e1b59542ee"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aab9cd218457e4fa5ce3bb6e1b59542ee">&#9670;&nbsp;</a></span>create_timer()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">flow::util::Timer ipc::util::sync_io::Timer_event_emitter::create_timer </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Creates idle timer for use with <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> subsequently. </p>
<p >It is associated with the thread started in the ctor, meaning completion handlers shall execute in that thread.</p>
<p >Formally, behavior is undefined if T is the returned timer or one moved-from it, and one invokes <code>T.async_wait()</code> on it; you must use <code>timer_async_wait(&amp;T, ...)</code> instead. You may call other <code>T</code> methods; in particular the <code>expires_*()</code> mutators will be useful. You may in particular call <code>T.cancel()</code> and destroy <code>T</code>. However see <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> regarding the effects of these various methods/calls.</p>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8cpp_source.html#l00039">39</a> of file <a class="el" href="timer__ev__emitter_8cpp_source.html">timer_ev_emitter.cpp</a>.</p>

<p class="reference">References <a class="el" href="timer__ev__emitter_8hpp_source.html#l00250">m_worker</a>.</p>

</div>
</div>
<a id="ad2124aadd5025490aedf16958db4599c" name="ad2124aadd5025490aedf16958db4599c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad2124aadd5025490aedf16958db4599c">&#9670;&nbsp;</a></span>create_timer_signal_pipe()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_event_emitter::Timer_fired_read_end</a> * ipc::util::sync_io::Timer_event_emitter::create_timer_signal_pipe </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Creates, and internally stores, an IPC mechanism instance intended for use with a given <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee" title="Creates idle timer for use with timer_async_wait() subsequently.">create_timer()</a>-returned <code>Timer</code>; returns pointer to the read-end of this mechanism. </p>
<p >The returned object is valid through <code>*this</code> lifetime.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735" title="Object representing the read end of IPC mechanism, where readable status indicates the associated tim...">Timer_fired_read_end</a> doc header for instructions on the acceptable/expected uses of the returned object.</dd></dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8cpp_source.html#l00046">46</a> of file <a class="el" href="timer__ev__emitter_8cpp_source.html">timer_ev_emitter.cpp</a>.</p>

<p class="reference">References <a class="el" href="timer__ev__emitter_8hpp_source.html#l00258">m_signal_pipe_readers</a>, <a class="el" href="timer__ev__emitter_8hpp_source.html#l00266">m_signal_pipe_writers</a>, and <a class="el" href="timer__ev__emitter_8hpp_source.html#l00250">m_worker</a>.</p>

</div>
</div>
<a id="a96f26e369ac1289b0a684d12f6bf07c3" name="a96f26e369ac1289b0a684d12f6bf07c3"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a96f26e369ac1289b0a684d12f6bf07c3">&#9670;&nbsp;</a></span>nickname()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">const std::string &amp; ipc::util::sync_io::Timer_event_emitter::nickname </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns nickname as passed to ctor. </p>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="a838497cd832da97bf1d52a7b8a85734c" name="a838497cd832da97bf1d52a7b8a85734c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a838497cd832da97bf1d52a7b8a85734c">&#9670;&nbsp;</a></span>timer_async_wait()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void ipc::util::sync_io::Timer_event_emitter::timer_async_wait </td>
          <td>(</td>
          <td class="paramtype">flow::util::Timer *&#160;</td>
          <td class="paramname"><em>timer</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a> *&#160;</td>
          <td class="paramname"><em>read_end</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>To be used on a timer <code>T</code> returned by <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee" title="Creates idle timer for use with timer_async_wait() subsequently.">create_timer()</a>, this is the replacement for the usual <code>T.async_wait(F)</code> call that loads a completion handler to execute at the expiration time. </p>
<p >Instead of supplying the completion handler <code>F()</code>, one supplies a read-end returned by <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a>; when the timer fires a payload shall be written to the associated write-end. You must call your <a class="el" href="namespaceipc_1_1util_1_1sync__io.html#aa0b9a3cc6bdc7dedbef4f9e06851aa24" title="In sync_io pattern, concrete type storing user-supplied function invoked by pattern-implementing ipc:...">Event_wait_func</a>, passing it an <a class="el" href="classipc_1_1util_1_1sync__io_1_1Asio__waitable__native__handle.html" title="Useful if using the sync_io pattern within a user event loop built on boost.asio (optionally with flo...">Asio_waitable_native_handle</a>, wrapping the handle in the same <code>*read_end</code>, ahead of this <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> call.</p>
<p >You may not call <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> on the same <code>*read_end</code> until one of the following things occurs:</p><ul>
<li>The timer fires; and the user event loop's async-wait indeed wakes up and passes that to your object; and your object therefore invokes <code>consume_timer_firing_signal(read_end)</code>.</li>
<li>The async-wait is <em>successfully</em> canceled: <code>T.cancel()</code> or <code>T.expires_*()</code> returns non-zero (in fact, 1).</li>
</ul>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">timer</td><td>The timer to arm. </td></tr>
    <tr><td class="paramname">read_end</td><td>A value returned by <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a>. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8cpp_source.html#l00081">81</a> of file <a class="el" href="timer__ev__emitter_8cpp_source.html">timer_ev_emitter.cpp</a>.</p>

<p class="reference">References <a class="el" href="timer__ev__emitter_8hpp_source.html#l00266">m_signal_pipe_writers</a>, and <a class="el" href="ipc__core_2src_2ipc_2util_2detail_2util_8cpp_source.html#l00067">ipc::util::pipe_produce()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter_a838497cd832da97bf1d52a7b8a85734c_cgraph.svg" width="344" height="59"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<h2 class="groupheader">Friends And Related Function Documentation</h2>
<a id="a07ebecd1cab6bf716b3482047e67eeb9" name="a07ebecd1cab6bf716b3482047e67eeb9"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a07ebecd1cab6bf716b3482047e67eeb9">&#9670;&nbsp;</a></span>operator&lt;&lt;()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">std::ostream &amp; operator&lt;&lt; </td>
          <td>(</td>
          <td class="paramtype">std::ostream &amp;&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html">Timer_event_emitter</a> &amp;&#160;</td>
          <td class="paramname"><em>val</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">related</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Prints string representation of the given <code><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html" title="An object of this type, used internally to implement sync_io-pattern objects that require timer event...">Timer_event_emitter</a></code> to the given <code>ostream</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Stream to which to write. </td></tr>
    <tr><td class="paramname">val</td><td>Object to serialize. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>os</code>. </dd></dl>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8cpp_source.html#l00131">131</a> of file <a class="el" href="timer__ev__emitter_8cpp_source.html">timer_ev_emitter.cpp</a>.</p>

<p class="reference">References <a class="el" href="timer__ev__emitter_8hpp_source.html#l00244">m_nickname</a>.</p>

</div>
</div>
<h2 class="groupheader">Member Data Documentation</h2>
<a id="a63c1e77a76775134b5a6d4725d58be81" name="a63c1e77a76775134b5a6d4725d58be81"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a63c1e77a76775134b5a6d4725d58be81">&#9670;&nbsp;</a></span>m_nickname</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">const std::string ipc::util::sync_io::Timer_event_emitter::m_nickname</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Nickname as passed to ctor. </p>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8hpp_source.html#l00244">244</a> of file <a class="el" href="timer__ev__emitter_8hpp_source.html">timer_ev_emitter.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="timer__ev__emitter_8cpp_source.html#l00131">operator&lt;&lt;()</a>.</p>

</div>
</div>
<a id="afafdfa9e2c522cd3e12b4f1915f83b56" name="afafdfa9e2c522cd3e12b4f1915f83b56"></a>
<h2 class="memtitle"><span class="permalink"><a href="#afafdfa9e2c522cd3e12b4f1915f83b56">&#9670;&nbsp;</a></span>m_signal_pipe_readers</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">std::vector&lt;boost::movelib::unique_ptr&lt;<a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a>&gt; &gt; ipc::util::sync_io::Timer_event_emitter::m_signal_pipe_readers</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>The readers (never null) returned by <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a>. </p>
<p >The order is immaterial, as this is just a place <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ac2e6652bed4a80239d57a7fad2bab47c" title="Stores the write-ends of the pipes created in create_timer_signal_pipe(), indexed by pointer to their...">m_signal_pipe_writers</a> map keys can point into. Wrapped into <code>unique_ptr</code>, so that the address of a <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735" title="Object representing the read end of IPC mechanism, where readable status indicates the associated tim...">Timer_fired_read_end</a> (as returned by <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a>) remains valid until <code>*this</code> dies. </p>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8hpp_source.html#l00258">258</a> of file <a class="el" href="timer__ev__emitter_8hpp_source.html">timer_ev_emitter.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="timer__ev__emitter_8cpp_source.html#l00046">create_timer_signal_pipe()</a>.</p>

</div>
</div>
<a id="ac2e6652bed4a80239d57a7fad2bab47c" name="ac2e6652bed4a80239d57a7fad2bab47c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac2e6652bed4a80239d57a7fad2bab47c">&#9670;&nbsp;</a></span>m_signal_pipe_writers</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">boost::unordered_map&lt;<a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a1533a54927a64579fda02c61ec94b735">Timer_fired_read_end</a>*, boost::movelib::unique_ptr&lt;boost::asio::writable_pipe&gt; &gt; ipc::util::sync_io::Timer_event_emitter::m_signal_pipe_writers</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Stores the write-ends of the pipes created in <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#ad2124aadd5025490aedf16958db4599c" title="Creates, and internally stores, an IPC mechanism instance intended for use with a given create_timer(...">create_timer_signal_pipe()</a>, indexed by pointer to their respective read-ends. </p>
<p ><a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a> can therefore look-up a write-end based on the read-end pointer it gave to the user, which the user must pass-to <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#a838497cd832da97bf1d52a7b8a85734c" title="To be used on a timer T returned by create_timer(), this is the replacement for the usual T....">timer_async_wait()</a>. </p>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8hpp_source.html#l00266">266</a> of file <a class="el" href="timer__ev__emitter_8hpp_source.html">timer_ev_emitter.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="timer__ev__emitter_8cpp_source.html#l00046">create_timer_signal_pipe()</a>, and <a class="el" href="timer__ev__emitter_8cpp_source.html#l00081">timer_async_wait()</a>.</p>

</div>
</div>
<a id="ad17e799f7c36c4c0cbc858637377f456" name="ad17e799f7c36c4c0cbc858637377f456"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad17e799f7c36c4c0cbc858637377f456">&#9670;&nbsp;</a></span>m_worker</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">flow::async::Single_thread_task_loop ipc::util::sync_io::Timer_event_emitter::m_worker</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>The thread where (only) timer-firing events (from <a class="el" href="classipc_1_1util_1_1sync__io_1_1Timer__event__emitter.html#aab9cd218457e4fa5ce3bb6e1b59542ee" title="Creates idle timer for use with timer_async_wait() subsequently.">create_timer()</a>-created <code>Timer</code>s) execute. </p>

<p class="definition">Definition at line <a class="el" href="timer__ev__emitter_8hpp_source.html#l00250">250</a> of file <a class="el" href="timer__ev__emitter_8hpp_source.html">timer_ev_emitter.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="timer__ev__emitter_8cpp_source.html#l00039">create_timer()</a>, <a class="el" href="timer__ev__emitter_8cpp_source.html#l00046">create_timer_signal_pipe()</a>, and <a class="el" href="timer__ev__emitter_8cpp_source.html#l00030">Timer_event_emitter()</a>.</p>

</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>util/sync_io/detail/<a class="el" href="timer__ev__emitter_8hpp_source.html">timer_ev_emitter.hpp</a></li>
<li>util/detail/<a class="el" href="detail_2util__fwd_8hpp_source.html">util_fwd.hpp</a></li>
<li>util/sync_io/detail/<a class="el" href="timer__ev__emitter_8cpp_source.html">timer_ev_emitter.cpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu May 2 2024 23:56:40 for Flow-IPC by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
